﻿#region Using

using System.Collections.ObjectModel;
using Microsoft.Xna.Framework.Input;
using XNgine.Services;

#endregion

namespace XNgine.Input
{
    /// <summary>
    /// An input device that manages the Keyboard and KeyboardState
    /// </summary>
    public class KeyboardDevice : InputDevice<KeyboardState>, IKeyboardDevice
    {
        private Collection<Keys> lastPressedKeys;
        private KeyboardState lastState;

        private KeyboardState currentState;

        public override KeyboardState State
        {
            get { return currentState; }
        }

        private Collection<Keys> _pressedKeys;

        public Collection<Keys> PressedKeys
        {
            get { return _pressedKeys; }
        }

        private Collection<Keys> _heldKeys;

        public Collection<Keys> HeldKeys
        {
            get { return _heldKeys; }
        }

        private Collection<Keys> _releasedKeys;

        public Collection<Keys> ReleasedKeys
        {
            get { return _releasedKeys; }
        }

        public event KeyPressedHandler KeyPressed;
        public event KeyHeldHandler KeyHeld;
        public event KeyReleasedHandler KeyReleased;

        public override void Initialize()
        {
            lastState = Keyboard.GetState();
        }

        public override void Update()
        {
            currentState = Keyboard.GetState();
            Collection<Keys> currentPressedKeys = new Collection<Keys>(currentState.GetPressedKeys());
            lastPressedKeys = new Collection<Keys>(lastState.GetPressedKeys());
            lastState = currentState;

            _pressedKeys = new Collection<Keys>();
            _heldKeys = new Collection<Keys>();
            _releasedKeys = new Collection<Keys>();

            // Loading Event Lists
            foreach (Keys key in currentPressedKeys)
            {
                if (lastPressedKeys.Contains(key))
                    _heldKeys.Add(key);
                else
                    _pressedKeys.Add(key);
            }
            foreach (Keys key in lastPressedKeys)
            {
                if (!currentPressedKeys.Contains(key))
                    _releasedKeys.Add(key);
            }

            // Event Calls
            if (KeyPressed != null && _pressedKeys.Count > 0)
                KeyPressed(_pressedKeys);
            if (KeyHeld != null && _heldKeys.Count > 0)
                KeyHeld(_heldKeys);
            if (KeyReleased != null && _releasedKeys.Count > 0)
                KeyReleased(_releasedKeys);
        }
    }
}